package com.aw.baselib.net.callback

import android.net.ParseException
import com.aw.baselib.R
import com.aw.baselib.base.AwBaseApplication
import com.aw.baselib.base.AwResponseBean
import com.aw.baselib.bean.rx.EventReLoginType
import com.aw.baselib.net.error.ApiException
import com.aw.baselib.util.AwLog.d
import com.google.gson.JsonParseException
import io.reactivex.observers.ResourceObserver
import org.greenrobot.eventbus.EventBus
import org.json.JSONException
import retrofit2.HttpException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException

/**
 * @author liushikai
 * @version 1
 * @date 2018/12/17
 * @describe 自定义的默认观察者
 */
class AwApiObserver<T : AwResponseBean<*>?>
/**
 * 构造方法
 */(private val mRspCallback: AwApiCallback<T>?) : ResourceObserver<T>() {
    override fun onStart() {
        super.onStart()
        if (null == mRspCallback) {
            return
        }
        mRspCallback.onStart()
    }

    /**
     * 请求有结果的时候，根据返回的结果码判断是否成功调用相应的方法
     *
     * @param rspBean 服务器返回的数据
     */
    override fun onNext(rspBean: T) {
        if (null == mRspCallback) {
            d("===AwRspConsumer callback is null, return")
            return
        } else {
            if (rspBean == null) {
                mRspCallback.onFail(
                    UNKNOWN_CODE,
                    AwBaseApplication.instance?.getString(R.string.common_server_return_empty_data)
                )
            } else if (rspBean.isTokenError) {
                EventBus.getDefault().postSticky(EventReLoginType(null))
            } else if (rspBean.isSuccess) {
                mRspCallback.onSuccess(rspBean.data as T)
            } else {
                mRspCallback.onFail(rspBean.code, rspBean.msg)
            }
            mRspCallback.onCompleted()
        }
    }

    /**
     * 请求超时或者是连接服务器失败（服务器响应结果是404或502及其他错误时），根据错误匹配出响应的信息。
     *
     */
    override fun onError(e: Throwable) {
        d("Retrofit网络请求", "Retrofit处理服务器响应数据:" + e.message)
        e.printStackTrace()
        if (null == mRspCallback) {
            return
        }
        if (e is HttpException || e is UnknownHostException) {
            mRspCallback.onFail(
                UNKNOWN_CODE,
                AwBaseApplication.instance?.getString(R.string.common_net_server_abnormal_request)
            )
        } else if (e is SocketTimeoutException) {
            mRspCallback.onFail(
                UNKNOWN_CODE,
                AwBaseApplication.instance?.getString(R.string.common_net_server_abnormal_timeout)
            )
        } else if (e is ConnectException) {
            mRspCallback.onFail(
                UNKNOWN_CODE,
                AwBaseApplication.instance?.getString(R.string.common_net_server_abnormal_connect)
            )
        } else if (e is JsonParseException
            || e is JSONException
            || e is ParseException
        ) {
            mRspCallback.onFail(
                UNKNOWN_CODE,
                AwBaseApplication.instance?.getString(R.string.common_net_server_abnormal_parse)
            )
        } else if (e is ApiException) {
            val exception = e
            if (exception.isTokenExpried) {
                //处理token失效对应的逻辑
                EventBus.getDefault().postSticky(EventReLoginType(null))
            } else {
                mRspCallback.onFail(exception.errorCode, exception.msg)
            }
        } else {
            if (e.message != null && e.message!!.contains("failed") || e.message!!.contains("Failed")) {
                mRspCallback.onFail(
                    UNKNOWN_CODE,
                    AwBaseApplication.instance?.getString(R.string.common_net_abnormal)
                )
            } else {
                mRspCallback.onFail(UNKNOWN_CODE, e.message)
            }
        }
        onComplete()
    }

    /**
     * 请求异常
     *
     * @param reason 异常代号
     */
    fun onException(reason: ExceptionReason?) {
        when (reason) {
            ExceptionReason.CONNECT_ERROR -> {}
            ExceptionReason.CONNECT_TIMEOUT -> {}
            ExceptionReason.BAD_NETWORK -> {}
            ExceptionReason.PARSE_ERROR -> {}
            ExceptionReason.UNKNOWN_ERROR -> {}
            else -> {}
        }
    }

    /**
     * 请求网络失败原因
     */
    enum class ExceptionReason {
        /**
         * 解析数据失败
         */
        PARSE_ERROR,

        /**
         * 网络问题
         */
        BAD_NETWORK,

        /**
         * 连接错误
         */
        CONNECT_ERROR,

        /**
         * 连接超时
         */
        CONNECT_TIMEOUT,

        /**
         * 未知错误
         */
        UNKNOWN_ERROR
    }

    /**
     * 请求完成后调用,在onNext之后
     * TODO
     */
    override fun onComplete() {
        if (null == mRspCallback) {
            return
        }
        mRspCallback.onCompleted()
    }

    companion object {
        const val UNKNOWN_CODE = -1
    }
}